home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / DSHJ2 / BEND.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-10  |  24.7 KB  |  1,044 lines

  1. #include    "defs.h"
  2. #include    "comp.h"
  3. #include    "cmd.h"
  4. #include     "osbind.h"
  5.  
  6. #define        MAXCMD        100        /* # commands in line    */
  7. #define        MAXCHR        800        /* # char/cmd in line    */
  8. #define        tsp        119        /* flash pos Thin SPace    */
  9. #define        nsp        120        /* flash pos eN   SPace    */
  10. #define        msp        121        /* flash pos eM   SPace    */
  11.  
  12. /*
  13.     Externals
  14. */
  15. extern    char        *realloc();
  16. extern    unsigned char    ptsfpos[256],
  17.             mcsdbl[303];        /* IFont Layout tables    */
  18. extern    struct slvll    *slv;            /* local GO slave list    */
  19. extern    int        vpage_size;        /* Vertical Page Size    */
  20.  
  21. /* ATARI */
  22. extern  int ptsarray[];
  23.  
  24. /*
  25.     Locals
  26. */
  27. static
  28. char        ker, ichfg, fhfg, rvofg;    /* some local flags    */
  29. static
  30. char        Kapp;                /* Kerning apply flag    */
  31. static
  32. int        splen;                /* space length holder    */
  33. static
  34. unsigned    spcnt, ispcnt, ccnt, cmdcnt;    /* various counters    */
  35. static
  36. unsigned    prepos;                /* PREvious char POS.    */
  37. static
  38. unsigned    ichcnt, ichwid,            /* Insert CHar. vars    */
  39.         ichpos[MAXCMD];
  40. static
  41. unsigned    rvopsiz, topval, botval,    /* Reverse Video vars    */
  42.         pvlsp, pvbot;
  43. static
  44. unsigned long    cmdrec[MAXCMD];            /* tag CoMmanD RECord    */
  45. static    struct {
  46.     unsigned char    acf;            /* floating accent flag    */
  47.     unsigned    pos;            /* position in chinln[]    */
  48. }    chs;                    /* CHar. State struct.    */
  49. static    struct {
  50.     unsigned char    fg;            /* char flag from font    */
  51.     unsigned char    ch;            /* its flash position    */
  52.     int        wid;            /* its composed width    */
  53. }    chinln[MAXCHR];                /* Char. IN LiNe array    */
  54.  
  55. /*
  56.     Globals
  57. */
  58. char        fofg;                /* Flash Only flag    */
  59. char        cpjm;                /* line justified mode    */
  60. char        advld, rldld;            /* Accumulative leading    */
  61. unsigned    disp;                /* Xdisplacement from 0    */
  62. unsigned char    *utinpt;            /* slave input pointer    */
  63. struct slvll    *Bslv;                /* Bend slave list ptr    */
  64. unsigned    init_x;                /* initial X from Atari    */
  65. unsigned long    init_y;                /* initial Y from Atari    */
  66. unsigned long    last_y;                /* Bend last Y known    */
  67. int        TYF_handle;            /* TYsetter file handle    */
  68. int        TYF_Gx0, TYF_Gy0;        /* Graphics file X0,Y0,    */
  69. int        TYF_Gx1, TYF_Gy1;        /* Graphics file X1,Y1,    */
  70. int        TYF_Gtype;            /* Graphics file type,    */
  71. char        *TYF_Gfile;            /* filename or cmd ptr    */
  72.  
  73.  
  74. /*
  75.     Justification & Slave generation processor.
  76.     Only called by dotext(). Returns pointer to next text
  77.     if cpabt is 0 or 8 else -1L for all other true values
  78.     of cpabt. Set
  79.     cpabt:    0    -- no error
  80.         4    -- line measure too short
  81.         7    -- no memory for tag support
  82.         8    -- Hit Region Feed
  83. */
  84. unsigned char    *bend(text,done)
  85. struct textobj    *text;
  86. int        *done;
  87. {
  88.     unsigned char    *inptr, c, noerr;
  89.  
  90.     cpabt = 0;
  91.     if (text->begtext >= free_start) {    /* no text return...    */
  92.         *done = 1;
  93.         return(-1L);
  94.     }
  95.     else    *done = 0;
  96.     setslvlist(text);            /* setup slave list    */
  97.     if (cpabt == 7)                /* memory error quit...    */
  98.         return(-1L);
  99.     initbcomp();                /* initialize Bend vars    */
  100.     inptr = text->begtext;            /* set text scan pter    */
  101.     while (!cpabt && inptr < free_start)    /* until end of buffer    */
  102.     switch(c = *inptr++) {
  103.     case ' ':                    /* space band    */
  104.         Kapp = 0;
  105.         cmpval = avcval = 0;            /* no CComp...    */
  106.         prepos = ccnt;
  107.         chinln[ccnt].fg = 0;
  108.         chinln[ccnt].ch = SPC;
  109.         splen += (chinln[ccnt++].wid    /* update space length    */
  110.               = cwfrw(spbval,0));    /* by min space band... */
  111.         ++spcnt;            /* update space counter    */
  112.         break;
  113.     case hrt:                    /* hard return    */
  114.     case srt:                    /* soft return    */
  115.     case Rf:                    /* Region Feed    */
  116.         if (line_ck())                /* final check    */
  117.             goto out;            /* error quit..    */
  118.         inptr += 2;                /* skip cr-lf    */
  119.         if (c == Rf)                /* Region Feed    */
  120.             cpabt = 8;            /* Stop now...    */
  121.         else
  122.         if (dpreset())                /* reach depth?    */
  123.             goto out;
  124.         break;
  125.     case cr:                    /* carr. return    */
  126.         ++inptr;                /* skip over lf    */
  127.         break;
  128.     case DH:                    /* disc. hyphen    */
  129.     case lf:                    /* line feed    */
  130.         break;                    /* ignore them    */
  131.     case QL:                    /* quad left    */
  132.         Kapp = 0;
  133.         cpjm = AL;
  134.         break;
  135.     case QR:                    /* quad right    */
  136.         Kapp = 0;
  137.         cpjm = AR;
  138.         break;
  139.     case QC:                    /* quad center    */
  140.         Kapp = 0;
  141.         cpjm = AC;
  142.         break;
  143.     case STAG:                    /* start TAG    */
  144.         in_tag(*inptr++,0,1);
  145.         cmpval = avcval = 0;            /* no CComp...    */
  146.         Kapp = 0;
  147.             break;
  148.     case ETAG:                    /* end    TAG    */
  149.         out_tag(*inptr++,0,1);
  150.         cmpval = avcval = 0;            /* no CComp...    */
  151.         Kapp = 0;
  152.             break;
  153.     case PTAG:                    /* PI TAG    */
  154.         storech(*inptr++);
  155.             break;
  156.     case sHY: case sDH:                /* soft hyphens    */
  157.         c = '-'; 
  158.     default:                    /* other chars    */
  159.         bcwidth(c);
  160.         break;
  161.     }
  162.     if (ccnt && !cpabt)            /* if there are chars..    */
  163.         line_ck();            /* final check on line    */
  164.  
  165. out:    funct_comm(SLVEOB,0);            /* place End Of Block    */
  166.     noerr = (!cpabt || cpabt == 8);
  167.     *done = (noerr && inptr >= free_start);
  168.     if (noerr) {
  169.         last_y = init_y + cdep;        /* save last Y known    */
  170.         Bslv->bufptr = realloc        /* reallocate slave...    */
  171.             (Bslv->bufptr,utinpt - Bslv->bufptr);
  172.     }
  173.     return(noerr ? inptr:(unsigned char *)-1L);
  174. }
  175.  
  176. /*
  177.     Routine to reset some composition parameters for new line
  178. */
  179. Lreset()
  180. {
  181.     disp    = init_x;
  182.     smsz    = cp.ssiz;
  183.     cpjm    = cp.jstmd;
  184.     ispcnt    = spcnt = ichcnt = cmdcnt = ccnt = cct = 0;
  185.     clen    = splen = ichwid = 0;
  186.     rvopsiz    = 0;
  187.     ichfg    = fhfg = 0;
  188.     chs.acf = 0;
  189.     chs.pos = 0;
  190.     Kapp    = 0;
  191.     cmpval  = avcval = 0;
  192. }
  193.  
  194. /*
  195.     Routine to intialize all default composition parameters
  196.     on entry to Bend()...
  197. */
  198. initbcomp()
  199. {
  200.     advld    = rldld = 0;
  201.     pvbot    = pvlsp = 0;
  202.     fofg    = 0;
  203.     spbval  = cp.minsp + cp.prfsp;        /* set space value...    */
  204.     cdep    = cp.lnsp;            /* set start depth    */
  205.     rvofg    = cp.rvomd;
  206.     Bslv    = slv;
  207.     utinpt    = Bslv->bufptr;            /* init slave pointer    */
  208.     Lreset();                /* reset line vars...    */
  209.     funct_comm(pt_typ,cp.ptsz);            /* setup point,    */
  210.     funct_comm(s_size,cp.ssiz);            /* set size    */
  211.     typeface(cp.font);            /* place Font info...    */
  212.     to_new_y();                /* place move FWD | REV    */
  213. }
  214.  
  215. /*
  216.     Routine to return current Char. Comp. value (Auto + Manual)
  217. */
  218. chcomp()
  219. {
  220.     int    temp = 0;
  221.  
  222.     if (cp.mcomp) {
  223.         temp += cmpval;
  224.         if (!chs.acf)
  225.             cmpval = cp.mcomp;
  226.     }
  227.     if (cp.acomp) {
  228.         temp += avcval;
  229.         if (!chs.acf)
  230.             avcval = acmp;
  231.     }
  232.     return(temp);
  233. }
  234.  
  235. /*
  236.     Routine to advance Bend depth
  237. */
  238. dpreset()
  239. {
  240.     if ((cdep + cp.lnsp) >= cp.depth)    /* break point reached    */
  241.         return(1);
  242.     else {
  243.         ad_dp();
  244.         Lreset();            /* reset for next line    */
  245.         return(0);
  246.     }
  247. }
  248.  
  249. /*
  250.     Function to do final line check (space justification and
  251.     slave generation)
  252. */
  253. line_ck()
  254. {
  255.     int    erf = 0;
  256.  
  257.     if (chs.acf) {                /* Faccent only at eol    */
  258.         ++cct;                    /* count it...    */
  259.         clen += chinln[chs.pos].wid;
  260.     }
  261.     if (cct || ichcnt)            /* some chars in line    */
  262.         erf = just_space(cp.llen-splen-clen);    /* go justify    */
  263.     else {                    /* or some cmds or none    */
  264.         if (rvofg)            /* check RVO to setup    */
  265.             set_rev_par();
  266.         if (cmdcnt)            /* if some cmds do them    */
  267.             funct_call(0,0,0,0);
  268.         if (rvofg)            /* check RVO to close    */
  269.             rev_video(OFF);
  270.     }
  271.     return(erf);
  272. }
  273.  
  274. /*
  275.     Function to justify extra space in line...
  276. */
  277. just_space(ex_sp)
  278. int    ex_sp;
  279. {
  280.     int    i, v, val, chct;
  281.     int    minlsp, maxlsp, cw;
  282.  
  283.     if (ichcnt) {                    /* IC cmd(s) ?    */
  284.       if (ex_sp < 0)                /* if no space    */
  285.         for (i = 0;i < ichcnt;++i)        /* find all ICs    */
  286.             chinln[ichpos[i]-1].fg = 0;    /* to disable..    */
  287.       else
  288.       if (ex_sp <= ichwid) {            /* enough space    */
  289.         for (i = 0;i < ichcnt;++i) {        /* for all ICs    */
  290.           cw = chinln[ichpos[i]].wid;        /* get IC width    */
  291.           if (cw <= ex_sp) {            /* space left ?    */
  292.             ex_sp -= cw;            /* (-) IC width    */
  293.             ichpos[i] = 1;            /* set min of 1    */
  294.           }
  295.           else    chinln[ichpos[i]-1].fg = 0;    /* or disable..    */
  296.         }
  297.         ichwid = 0;                /* no IC width    */
  298.       }
  299.     }
  300.  
  301.     if (cpjm != AJ &&            /* Non Justify mode and    */
  302.         ex_sp > 0 && !ispcnt && !ichcnt) {    /* extra space found..    */
  303.       if (cpjm == AR)                /* quad right    */
  304.         disp += ex_sp;                /* add to left    */
  305.       else
  306.       if (cpjm == AC)                /* quad center    */
  307.         disp += (ex_sp / 2);            /* add 1/2 only */
  308.     }
  309.  
  310.     if (rvofg)                /* check RVO to setup    */
  311.         set_rev_par();
  312.  
  313.     if (ex_sp < 0) {            /* Negative space case    */
  314.       if (!spcnt)                    /* no spaceband    */
  315.         v = minlsp = 0;                /* no (+) space    */
  316.       else {
  317.         v = cwfrw(cp.prfsp,1);            /* get Prf diff    */
  318.         minlsp = v * spcnt;            /* to (+) space    */
  319.       }
  320.       if ((ex_sp + minlsp) >= 0) {            /* Min|Prf range*/
  321.         ex_sp = ~ex_sp + 1;
  322.         funct_call(-(ex_sp/spcnt),-(ex_sp%spcnt),0,0);
  323.       }
  324.       else
  325.       if (cp.ltsmd && cp.nlts && cct > 1) {        /* LTSpace on    */
  326.         ex_sp += minlsp;            /* (+) space...    */
  327.         chct   = cct - 1;
  328.         minlsp = cwfrw(cp.nlts,1) * chct;    /* get LTS diff    */
  329.         if ((ex_sp + minlsp) >= 0) {        /* -LTS range    */
  330.           ex_sp = ~ex_sp + 1;
  331.           funct_call(-v,0,-(ex_sp/chct),-(ex_sp%chct));
  332.         }
  333.         else    cpabt = 4;            /* line overset    */
  334.       }
  335.       else    cpabt = 4;                /* line overset    */
  336.     }
  337.     else
  338.     if ((!ispcnt && !ichcnt) ||        /* no ISpace or IChar    */
  339.         ( ichcnt && !ichwid)) {        /* or IC being counted    */
  340.       if (cpjm == AJ && ex_sp && cct > 1) {    /* Justify & extra Sp    */
  341.         chct = cct - 1;
  342.         if (cp.plts) {                /* +LTS active    */
  343.           val = cwfrw(cp.plts,1);        /* get +LTS to    */
  344.           minlsp = val * chct;            /* spread extra    */
  345.         }
  346.         else
  347.           val = minlsp = 0;            /* no +LTS...    */
  348.         if (spcnt) {                /* Spacebands ?    */
  349.           v = cwfrw(cp.maxsp,1);        /* get MaxSp to    */
  350.           maxlsp = v * spcnt;            /* spread extra    */
  351.           if (    !cp.ltsmd ||            /* LTSpace off    */
  352.             ex_sp <= maxlsp  )        /* extra fit Sp    */
  353.                             /* spread to Sp    */
  354.             funct_call(ex_sp/spcnt,ex_sp%spcnt,0,0);
  355.           else {                /* +LTS range    */
  356.             ex_sp -= maxlsp;        /* take off Sp    */
  357.             if (ex_sp <= minlsp)        /* extra fit LTS*/
  358.                             /* spread to Ch    */
  359.               funct_call(v,0,ex_sp/chct,ex_sp%chct);
  360.             else {                /* extra > +LTS    */
  361.               ex_sp -= minlsp;
  362.               funct_call(v+(ex_sp/spcnt),ex_sp%spcnt,val,0);
  363.             }
  364.           }
  365.         }
  366.         else                    /* no space...    */
  367.         if (cp.ltsmd) {                /* LTSpace on    */
  368.           if (ex_sp < ((val *= 3) * chct))    /* extra <+3LTS    */
  369.             funct_call(0,0,ex_sp/chct,ex_sp%chct);
  370.           else    funct_call(0,0,val,0);        /* spread +3LTS    */
  371.               
  372.         }
  373.         else    funct_call(0,0,0,0);        /* just output    */
  374.       }
  375.       else    funct_call(0,0,0,0);        /* act as Non Justify    */
  376.     }
  377.     else
  378.     if (ex_sp > 0) {            /* Positive space case    */
  379.       if (ichcnt) {                /* there are IC(s)...    */
  380.         cw    = ex_sp / ichcnt;        /* spread to IC    */
  381.         val    = ex_sp % ichcnt;        /* extra remain    */
  382.         ex_sp    = 0;
  383.         for (i = 0;i < ichcnt;++i) {
  384.           if (val)
  385.             v = 1, --val;            /* use remain    */
  386.           else    v = 0;
  387.           if (    chinln[ichpos[i]].ch == msp ||    /* IC EM Space    */
  388.             chinln[ichpos[i]].ch == nsp ||    /* IC EN Space    */
  389.             chinln[ichpos[i]].ch == tsp  )    /* IC TH Space    */
  390.             chinln[ichpos[i]].wid = cw + v;
  391.           else {                /* IC normal Ch    */
  392.             if (chinln[ichpos[i]].wid) {    /* valid width    */
  393.               ex_sp += (chinln[ichpos[i]-1].wid =
  394.                  (cw+v)%chinln[ichpos[i]].wid);
  395.               if (cw)            /* set # of Ch    */
  396.                 ichpos[i]= (cw+v)/chinln[ichpos[i]].wid;
  397.             }
  398.             else { cpabt = 4; goto out; }    /* what ? error    */
  399.           }
  400.         }
  401.       }
  402.       if (ex_sp) {
  403.         if (ispcnt)                /* spread to IS    */
  404.             funct_call(ex_sp/ispcnt,ex_sp%ispcnt,0,0);
  405.         else
  406.         if (spcnt)                /* spread to Sp    */
  407.             funct_call(ex_sp/spcnt,ex_sp%spcnt,0,0);
  408.         else    funct_call(0,0,0,0);        /* all other Ch    */
  409.       }
  410.       else    funct_call(0,0,0,0);            /* just output    */
  411.     }
  412.     else    funct_call(0,0,0,0);        /* just output slave...    */
  413.  
  414. out:    if (rvofg)                /* check RVO to close    */
  415.         rev_video(OFF);
  416.     return(cpabt);
  417. }
  418.  
  419. /*
  420.     Slave generator and Extra space justificator
  421.     sw    : space width
  422.     ex_spw    : extra space remainder
  423.     cw    : LTS value on character
  424.     ex_chw    : extra LTS remainder
  425. */
  426. funct_call(sw,ex_spw,cw,ex_chw)
  427. int    sw, ex_spw, cw, ex_chw;
  428. {
  429.     int    i, j, k, l, v;
  430.  
  431.     i = k = l = 0;                    /* zero indexes    */
  432.  
  433.     while (i < ccnt && !cpabt) {        /* scan chinln[] for...    */
  434.  
  435.     if (chinln[i].ch == IC) {            /* Ins Char cmd    */
  436.       if (chinln[i].fg)                /* check valid    */
  437.       switch(chinln[++i].ch) {            /* check type    */
  438.       case SPC:                    /* word space    */
  439.         disp += (chinln[i].wid + sw);
  440.         if (ex_spw) {                /* space left..    */
  441.             --ex_spw;
  442.             ++disp;
  443.         }
  444.         break;
  445.       case msp: case nsp: case tsp:            /* fixed spaces    */
  446.         disp += chinln[i].wid;
  447.         ++k;                    /* bump ICcount    */
  448.         break;
  449.       default:                    /* other chars    */
  450.         if (chinln[i-1].wid && !ispcnt && !spcnt)
  451.         {                    /* space left..    */
  452.             v = chinln[i-1].wid % 2;
  453.                chinln[i-1].wid /= 2;
  454.             disp += (chinln[i-1].wid + v);
  455.         }
  456.         for (j = 0;j < ichpos[k];++j)
  457.         if (fhfg)                 /* no flash on    */
  458.             disp += chinln[i].wid;        /* skip width    */
  459.         else    long_char_for(chinln[i].ch,chinln[i].wid);
  460.         if (chinln[i-1].wid && !ispcnt && !spcnt)
  461.             disp += chinln[i-1].wid;    /* space left..    */
  462.         ++k;                    /* bump ICcount    */
  463.         break;
  464.       }
  465.       else    ++i;                    /* else skip it    */
  466.     }
  467.     else
  468.     if (chinln[i].ch == CMDCH) {            /* Tag commands    */
  469.       switch(chinln[i].wid) {
  470.       case 1:                    /* point size    */
  471.         funct_comm(pt_typ,(int)cmdrec[l]);
  472.         break;
  473.       case 2:                    /* set size    */
  474.         funct_comm(s_size,(int)cmdrec[l]);
  475.         break;
  476.       case 3:                    /* Font        */
  477.         typeface((int)cmdrec[l]);
  478.         break;
  479.       case 4:                    /* Adv leading    */
  480.         funct_comm(ver_mov_for,(int)cmdrec[l]);
  481.         break;
  482.       case 5:                    /* Rev leading    */
  483.         funct_comm(ver_mov_rev,(int)cmdrec[l]);
  484.         break;
  485.       case 6:                    /* Move Right    */
  486.         disp += (unsigned)cmdrec[l];
  487.         break;
  488.       case 7:                    /* Move Left    */
  489.         disp -= (unsigned)cmdrec[l];
  490.         break;
  491.       case 11:                    /* Rev. Video    */
  492.         if (cmdrec[l]) {
  493.             set_rev_par();
  494.             rvofg = ON;
  495.         }
  496.         else    rev_video(rvofg = OFF);
  497.         break;
  498.       case 14:                    /* Flash Only    */
  499.         fhfg = (char)cmdrec[l];
  500.         break;
  501.       }
  502.       ++l;                        /* next command    */
  503.     }
  504.     else
  505.     if (chinln[i].ch == SPC) {            /* word space    */
  506.       if (!ispcnt || sw < 0 || ex_spw < 0) {
  507.         if (ex_spw > 0)
  508.         {--ex_spw; ++chinln[i].wid;}
  509.         if (ex_spw < 0)
  510.         {++ex_spw; --chinln[i].wid;}
  511.         disp += (chinln[i].wid + sw);
  512.       }
  513.       else    disp += chinln[i].wid;
  514.     }
  515.     else {                        /* other chars    */
  516.       if (chinln[i].ch == msp ||
  517.           chinln[i].ch == nsp ||
  518.           chinln[i].ch == tsp) {            /* fixed spaces    */
  519.         if (!ispcnt) {
  520.           if (ex_spw > 0)
  521.           {--ex_spw; ++chinln[i].wid;}
  522.           if (ex_spw < 0)
  523.           {++ex_spw; --chinln[i].wid;}
  524.         }
  525.         disp += chinln[i].wid;
  526.       }
  527.       else {                    /* all others..    */
  528.         if (cw || ex_chw) {
  529.           if (chinln[i].fg & 0x04)        /* accent char    */
  530.             chinln[i].wid += (cw / 2);
  531.           else {                /* normal char    */
  532.             chinln[i].wid += cw;
  533.             if (ex_chw > 0)
  534.             {--ex_chw; ++chinln[i].wid;}
  535.             if (ex_chw < 0)
  536.             {++ex_chw; --chinln[i].wid;}
  537.           }
  538.         }
  539.         if (fhfg)                 /* no flash on    */
  540.             disp += chinln[i].wid;        /* skip width    */
  541.         else    long_char_for(chinln[i].ch,chinln[i].wid);
  542.       }
  543.     }
  544.  
  545.     ++i;                    /* next in chinln[]...    */
  546.     }                    /* end of scan loop...    */
  547.  
  548.     if (cp.rvomd && cct)
  549.         pvlsp = (unsigned)cp.lnsp;
  550.     else    pvbot = pvlsp = 0;
  551.     if (setp.omod == 2) {            /* for CG 8200 only    */
  552.         funct_comm(hor_mov_dir,1);
  553.         funct_comm(hor_pos,0);
  554.         funct_comm(hor_mov_dir,0);
  555.     }
  556. }
  557.  
  558. /*
  559.     Routine to setup Typeface info
  560. */
  561. typeface(ftn)
  562. int    ftn;
  563. {
  564.     if (ckfont(ftn)) {            /* set font pointer    */
  565.         loadrval();            /* load Rev Video vals    */
  566.         funct_comm(ty_face,ftn,pftpt+2);/* place font # command    */
  567.     }
  568. }
  569.  
  570. /*
  571.     Function to get flash position, store it then
  572.     calculate its width.
  573. */
  574. bcwidth(c)
  575. unsigned char    c;
  576. {
  577.     unsigned char    fp;
  578.     unsigned    i;
  579.  
  580.     if (c == TSP)                /* all fixed spaces...    */
  581.         fp = tsp;
  582.     else
  583.     if (c == NSP)
  584.         fp = nsp;
  585.     else
  586.     if (c == MSP)
  587.         fp = msp;
  588.     else    fp = ptsfpos[c];        /* get flash position    */
  589.     if (fp == 254) {            /* if doublet case...    */
  590.         for (i = 0;
  591.              i < 303 && mcsdbl[i] != c;    /* find it in table...    */
  592.              i += 3);
  593.         if (i >= 303) {            /* no match error...    */
  594.             chs.acf = 0;
  595.             return;
  596.         }
  597.         if (!storech(mcsdbl[i+1]))    /* do floating accent    */
  598.             return;
  599.         fp = mcsdbl[i+2];        /* then normal char.    */
  600.     }
  601.     storech(fp);
  602. }
  603.  
  604. /*
  605.     Routine to store flash position and calculate its width.
  606. */
  607. storech(fp)
  608. unsigned char    fp;
  609. {
  610.     if (fp > msp || !width(fp))
  611.         return(chs.acf = 0);
  612.     else    return(1);
  613. }
  614.  
  615. /*
  616.     Routine to calculate Bend character width.
  617. */
  618. width(fp)
  619. unsigned char    fp;
  620. {
  621.     int        cw, aw, kerval;
  622.     unsigned char    rw, *p;
  623.  
  624.     p = pftpt + 49 + (unsigned)fp * 2;    /* offset to get width    */
  625.     if ((rw = *p) != 0xff) {
  626.       cw = cwfrw(rw,0);
  627.       if (chs.acf) {
  628.         chs.acf = 0;
  629.         cw -= chcomp();
  630.         if (cw < 0) cw = 0;
  631.         kerval = bkerning(fp,1);
  632.         if (kerval)
  633.             subchwid(prepos,kerval);
  634.         prepos = ccnt;
  635.         aw = chinln[chs.pos].wid;
  636.         if (cw < aw) cw = aw;        /* Ch Width < Accent W    */
  637.         clen += (cw - aw);
  638.         chinln[ccnt   ].ch  = chinln[chs.pos].ch;
  639.         chinln[chs.pos].ch  = fp;    /* swap accent to 2nd    */
  640.         chinln[chs.pos].wid = (cw - aw) / 2;
  641.         chinln[ccnt   ].wid = cw - chinln[chs.pos].wid;
  642.         Kapp = 1;
  643.         ++cct;
  644.         ++ccnt;
  645.       }
  646.       else {
  647.         chinln[ccnt].fg = *(p + 1);
  648.         chs.acf = chinln[ccnt].fg & 0x04;    /* accent bit ?    */
  649.         chs.pos = ccnt;
  650.         cw -= chcomp();
  651.         if (cw < 0) cw = 0;
  652.         kerval = bkerning(fp,0);
  653.         if (fofg) {                /* flash only..    */
  654.           chinln[ccnt].wid = 0; 
  655.           if (!chs.acf)
  656.             fofg = 0;
  657.         }
  658.         else {
  659.           if (!chs.acf) {
  660.             if (kerval) {
  661.             clen -= kerval;
  662.             chinln[prepos].wid -= kerval;
  663.             if (chinln[prepos].wid < 0)
  664.                 chinln[prepos].wid = 0;
  665.             }
  666.           }
  667.           chinln[ccnt].wid = cw;
  668.           if (!ichfg) {
  669.             if (!chs.acf) {
  670.             ++cct;
  671.             prepos = ccnt;
  672.             Kapp = 1;
  673.             }
  674.             clen += chinln[ccnt].wid;
  675.           }
  676.           else {
  677.             ichwid += cw;
  678.             if (!chs.acf)
  679.             ichfg = 0;
  680.           }
  681.         }
  682.         chinln[ccnt++].ch= fp;
  683.       }
  684.       if (cp.rvomd && cp.ptsz > rvopsiz)
  685.         rvopsiz = cp.ptsz;
  686.       return(1);
  687.     }
  688.     else
  689.       return(0);
  690. }
  691.  
  692. char    bgetkerval(fp,mode)
  693. unsigned char    fp;
  694. int        mode;
  695. {
  696.     unsigned char    *ptr, v;
  697.     char        min = 127;
  698.     unsigned    i, found;
  699.  
  700.     if (!txkn)                /* no sector kerning    */
  701.         return(0);
  702.     ptr = pftpt + 289 + ((unsigned)fp * 4);
  703.     if (!Kapp)
  704.         ker = 0;
  705.     else
  706.     if (!mode)
  707.         ker ^= 1;
  708.     for (i = 0;i < 4;++i,++ptr) {
  709.       if (mode) {
  710.         if (kern[ker].rval[i] > (v = *ptr & 0x0f))
  711.         kern[ker].rval[i] = v;
  712.         if (kern[ker].lval[i] > (v = *ptr >> 4))
  713.         kern[ker].lval[i] = v;
  714.       }
  715.       else {
  716.         kern[ker].rval[i] = *ptr & 0x0f;
  717.         kern[ker].lval[i] = *ptr >> 4;
  718.       }
  719.     }
  720.     if (Kapp)
  721.     for (i = 0;i < 4;++i) {
  722.       if (ker) {
  723.         kern[0].rval[i] += kern[1].lval[i];
  724.         if (min > kern[0].rval[i])
  725.         min = kern[0].rval[i];
  726.       }
  727.       else {
  728.         kern[1].rval[i] += kern[0].lval[i];
  729.         if (min > kern[1].rval[i])
  730.         min = kern[1].rval[i];
  731.       }
  732.     }
  733.     else    return(0);
  734.     if (kpval)                /* if kern pair exist    */
  735.     for (    ptr = kpptr, i = found = 0;
  736.         i < kpval && !found;
  737.         ++i, ptr += 3    )
  738.     if (chinln[prepos].ch == *ptr && fp == *(ptr+1)) {
  739.         found = 1;
  740.         min += *(ptr+2);
  741.     }
  742.     return(min);
  743. }
  744.  
  745. bkerning(fp,mode)
  746. unsigned char    fp;
  747. int        mode;
  748. {
  749.     char    kval;
  750.  
  751.     if (!cp.kernmd)
  752.         return(0);
  753.     kval = bgetkerval(fp,mode);
  754.     if (kval) {
  755.       if (kval < 0) {
  756.         kval = ~kval + 1;
  757.         return(0 - cwfrw(kval,0));
  758.       }
  759.       else    return(cwfrw(kval,0));
  760.     }
  761.     else    return(0);
  762. }
  763.  
  764. subchwid(pos,val)
  765. int    pos, val;
  766. {
  767.     if (chinln[pos].fg & 0x04) {            /* accent bit ?    */
  768.         chinln[pos-1].wid -= (val / 2);
  769.         chinln[pos  ].wid -= (val - (val / 2));
  770.     }
  771.     else    chinln[pos].wid -= val;
  772.     if (chinln[pos].wid < 0)
  773.         chinln[pos].wid = 0;
  774.     clen -= val;
  775. }
  776.  
  777. loadrval()
  778. {
  779.     union {
  780.         unsigned char    arr[6];
  781.         unsigned    val[3];
  782.     } rvo;
  783.     f_move(pftpt + 45,rvo.arr,6);
  784.     topval = rvo.val[2] - rvo.val[0];    /* rvo top window value    */
  785.     botval = rvo.val[1] - rvo.val[2];    /* rvo bot window value    */
  786. }
  787.  
  788. ad_dp()
  789. {
  790.     cdep += cp.lnsp;                /* add LSpace    */
  791.     funct_comm(ver_mov_for,(unsigned)cp.lnsp);    /* move down    */
  792. }
  793.  
  794. rev_video(mode)
  795. int    mode;
  796. {
  797.     funct_comm(hor_pos,disp);
  798.     funct_comm(rev_typ,mode);
  799. }
  800.  
  801. set_rev_par()
  802. {
  803.     unsigned long    temp1, temp2;
  804.  
  805.     if (rvopsiz) {
  806.       temp1 = ((long)rvopsiz * (long)topval * 3L) / 2084L;
  807.       temp2 = ((long)rvopsiz * (long)botval * 3L) / 2084L;
  808.       if ((temp1 + (long)pvbot) <= (long)pvlsp) {
  809.         temp1 = (long)pvlsp - (long)pvbot;
  810.         temp2 = ((long)pvlsp / 2L) - (long)temp2;
  811.       }
  812.       funct_comm(rev_wind_top,(unsigned)temp1);
  813.       funct_comm(rev_wind_bot,(unsigned)temp2);
  814.       pvbot = (unsigned)temp2;
  815.     }
  816.     else {
  817.       funct_comm(rev_wind_top,0);
  818.       funct_comm(rev_wind_bot,0);
  819.     }
  820.     rev_video(ON);
  821. }
  822.  
  823. static    to_new_y()
  824. {
  825.     unsigned long    new_y;
  826.  
  827.     new_y = init_y + cp.lnsp;
  828.     if (new_y > last_y)
  829.         funct_comm(ver_mov_for,
  830.             (unsigned)(new_y - last_y));    /* move forward    */
  831.     else
  832.     if (new_y < last_y)
  833.         funct_comm(ver_mov_rev,
  834.             (unsigned)(last_y - new_y));    /* move bckward    */
  835. }
  836.  
  837. in_cmmd(funct,arg)
  838. int        funct;
  839. unsigned long    arg;
  840. {
  841.     chinln[ccnt  ].fg    = 0;
  842.     chinln[ccnt  ].ch    = CMDCH;    /* store Tag command    */
  843.     chinln[ccnt++].wid    = funct;    /* store functN type    */
  844.     cmdrec[cmdcnt++]    = arg;        /* store Tag argument    */
  845. }
  846.  
  847. IC_cmd(ch,fpmode)
  848. unsigned char    ch, fpmode;
  849. {
  850.     chinln[ccnt].fg  = 1;
  851.     chinln[ccnt].ch  = IC;            /* store IC command    */
  852.     chinln[ccnt].wid = 0;            /* no width for IC cmd    */
  853.     if (!fpmode && ch == ' ') {
  854.         ++ccnt;
  855.         ++ispcnt;
  856.         chinln[ccnt].ch  = SPC;        /* store SPC (space)    */
  857.         chinln[ccnt++].wid = 0;        /* no width for IC cmd    */
  858.     }
  859.     else {
  860.         ichpos[ichcnt++] = ++ccnt;    /* pos to be inserted    */
  861.         cmpval = avcval = 0;        /* no CComp for IChar    */
  862.         ichfg = 1;            /* set IC flag before    */
  863.         if (fpmode)
  864.             storech(ch);
  865.         else    bcwidth(ch);        /* setting up ch width    */
  866.     }
  867. }
  868.  
  869. static    BEfct0()
  870. {
  871.     int    i;
  872.  
  873.     i = setp.omod;
  874.     i <<= 8;
  875.     i += get_pgtype();
  876.     funct_comm(st_take,i);            /* place Start of Take    */
  877.     funct_comm(USRPGN,1);            /* place Start Page #    */
  878.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  879.     last_y = 0L;
  880. }
  881.  
  882. static    BEfct1()
  883. {
  884.     funct_comm(SLVEOD,0);            /* place End Of Data    */
  885. }
  886.  
  887. static    BEfct2()
  888. {
  889.     if (last_y > 0)                /* move to top page    */
  890.         funct_comm(ver_mov_rev,(unsigned)last_y);
  891.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  892.     last_y = 0L;
  893. }
  894.  
  895. static    BEfct3()
  896. {
  897.     funct_comm(next_pg,0);            /* use GOG next page    */
  898.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  899.     last_y = 0L;
  900. }
  901.  
  902. static    BEfct4()                /* For graphics mode 5    */
  903. {
  904.     funct_comm(graphic,TYF_Gtype);        /* insert VP command    */
  905.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  906. }
  907.  
  908. static    BEfct5()                /* For other gr. modes    */
  909. {
  910.     int    fbuff[5];
  911.  
  912.     funct_comm(graphic,TYF_Gtype);        /* insert VP command    */
  913.     fbuff[0] = strlen(TYF_Gfile) + 11;    /* place count    */
  914.     fbuff[1] = TYF_Gx0;            /* place x0    */
  915.     fbuff[2] = TYF_Gy0;            /* place y0    */
  916.     fbuff[3] = TYF_Gx1 - TYF_Gx0 + 1;    /* place Width    */
  917.     fbuff[4] = TYF_Gy1 - TYF_Gy0 + 1;    /* place Height    */
  918.     movcmds(fbuff,10);
  919.     movcmds(TYF_Gfile,fbuff[0] - 10);    /* place filename    */
  920.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  921. }
  922.  
  923. static    ins_slave(fct)
  924. int    (*fct)();
  925. {
  926.     struct textobj    temp;
  927.  
  928.     temp.slvlist = (struct slvll *)0;
  929.     setslvlist(&temp);
  930.     if (cpabt)
  931.         return(0);
  932.     Bslv    = slv;
  933.     utinpt    = Bslv->bufptr;            /* init slave pointer    */
  934.  
  935.     (*fct)();                /* do slave function    */
  936.  
  937.     if (cpabt)
  938.         return(0);
  939.     else    return(writeslv(temp.slvlist));
  940. }
  941.  
  942. Start_TYF()
  943. {
  944.     return(ins_slave(BEfct0));
  945. }
  946.  
  947. End_TYF()
  948. {
  949.     return(ins_slave(BEfct1));
  950. }
  951.  
  952. topPge_TYF()
  953. {
  954.     return(ins_slave(BEfct2));
  955. }
  956.  
  957. newPge_TYF()
  958. {
  959.     return(ins_slave(BEfct3));
  960. }
  961.  
  962. insGR_TYF(op,count,glgrattr)
  963. int    op, count;
  964. int    glgrattr[];
  965. {
  966.     int    fbuff[7];
  967.  
  968.     if (TYF_Gtype == 5) {            /* For graphics mode 5    */
  969.       if (!ins_slave(BEfct4))        /* insert VP command    */
  970.         return(0);
  971.       fbuff[0] = 36 + (4 * count);    /* count  + x0 + y0 + width +    */
  972.                       /* height + op + pts count +    */
  973.                     /* glgrattr + points        */
  974.       fbuff[1] = TYF_Gx0;            /* place x0    */
  975.       fbuff[2] = TYF_Gy0;            /* place y0    */
  976.       fbuff[3] = TYF_Gx1 - TYF_Gx0 + 1;    /* place Width    */
  977.       fbuff[4] = TYF_Gy1 - TYF_Gy0 + 1;    /* place Height    */
  978.       fbuff[5] = op;            /* place opcode    */
  979.       fbuff[6] = count;
  980.       Fwrite(TYF_handle,14L,fbuff);
  981.       Fwrite(TYF_handle,22L,glgrattr);
  982.       Fwrite(TYF_handle,(long)(4L*(long)count),ptsarray);
  983.       return(1);
  984.     }
  985.     else    return(ins_slave(BEfct5));
  986. }
  987.  
  988. writeslv(slvlist)
  989. struct    slvll    *slvlist;
  990. {
  991.     struct    slvll    *slvptr = slvlist;
  992.     int        cnt, retc = 1;
  993.  
  994.     if (slvptr != (struct slvll *)0L) {
  995.       for (;;) {
  996.         cnt = countslaveB(slvptr->bufptr);
  997.         if (cnt && write(TYF_handle,slvptr->bufptr,cnt) != cnt)
  998.         {    retc = 0; break;    }
  999.         if (slvptr->fptr == (struct slvll *)0L)
  1000.             break;
  1001.         else    slvptr = slvptr->fptr;
  1002.       }
  1003.       freeslvlist(slvlist);
  1004.     }
  1005.     return(retc);
  1006. }
  1007.  
  1008. /*
  1009. */
  1010. countslaveB(sptr)
  1011. unsigned char    *sptr;
  1012. {
  1013.     unsigned char    command, *eptr;
  1014.     unsigned    code, brk, cmd_len, cnt;
  1015.  
  1016.     brk = cnt = 0;
  1017.     eptr = sptr + UTSIZE;
  1018.     do {
  1019.       code = get_argument(sptr);    /* get encoded word    */
  1020.       if (!(code & 0xFF00))        /* check if NULL cmd    */
  1021.         cmd_len = 1;
  1022.       else    cmd_len = 3;
  1023.       if ((code & 0x8080) == 0x8080) {
  1024.         command = *sptr & 0x7f;
  1025.         switch (command) {
  1026.         case (SLVEOD):            /* end of data    */
  1027.         brk = 1;    break;
  1028.         case (SLVEOB):            /* end of block    */
  1029.         brk = 2;    break;
  1030.         case (ty_face):            /* font command    */
  1031.         cmd_len = 9;    break;
  1032.         case (graphic):            /* VP command    */
  1033.         if (*(sptr+2) < 5)
  1034.           cmd_len += get_argument(sptr+3);
  1035.         break;
  1036.         }
  1037.       }
  1038.       sptr += cmd_len;
  1039.       if (brk != 2)
  1040.         cnt += cmd_len;
  1041.     } while (!brk && sptr < eptr);
  1042.     return(cnt);
  1043. }
  1044.